package es.exitae.ejerciciofinal.servicios;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Date;

import android.annotation.SuppressLint;
import android.content.ContentResolver;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Environment;
import android.widget.ImageView;
import es.exitae.ejerciciofinal.utils.Traza;
import es.exitae.ejerciciofinal.utils.enums.Metodo;
import es.exitae.pirateplace.R;

public class ServicioGestionImagenes
{
	public static final int REQUEST_CAMARA = 1;
	public static final int REQUEST_IMAGEN = 2;
	public static final int MEDIA_TYPE_IMAGE = 9;
	
	private int imagenPorDefecto;
	
	private ContentResolver cr;
	
	private Bitmap imagen;
	private Uri lastUri;
	
	public ServicioGestionImagenes(ContentResolver cr)
	{
		imagenPorDefecto = R.drawable.ic_launcher;
		this.cr = cr;
	}
	
	/**
	 * Actualiza la el componente de vista de la imagen con el bitmap del
	 * servicio, si este es null carga el bitmap por defecto;
	 * 
	 * @param imageView
	 * @return
	 */
	public ImageView actualizarImagenView(ImageView imageView)
	{
		Traza.d(Metodo.ENTRADA);
		if(imagen != null)
		{
			imageView.setImageBitmap(imagen);
		}else
		{
			imageView.setImageResource(imagenPorDefecto);
		}
		
		Traza.d(Metodo.SALIDA);
		return imageView;
	}
	
	/**
	 * Convierte el intent devuelto por la actividad para tomar foto. Devuelve
	 * true si hay foto y false si no la hay
	 * 
	 * @param Intent data
	 * @return boolean resultado
	 */
	public boolean cargarImagenDesdeIntent(Intent data)
	{
		Traza.d(Metodo.ENTRADA);
		boolean resultado = false;
		
		if(data == null)
		{
			Traza.w("Intent es null");
			return resultado;
		}
		
		if(data.hasExtra("data"))
		{
			if(imagen != null)
			{
				cleanMemory();
			}
			
			imagen = (Bitmap)data.getParcelableExtra("data");
			resultado = true;
		}else
		{
			Traza.w("No hay parametro 'data'");
		}
		
		Traza.d(Metodo.SALIDA);
		return resultado;
	}
	
	/**
	 * carga una imagen dada su URI, debuelbe tru si se cargo corectamente y
	 * false si hubo algun error
	 * 
	 * @param URI selectedImage
	 * @return boolean
	 */
	public boolean cargarImagenDesdeUri(Uri selectedImage)
	{
		Traza.d(Metodo.ENTRADA);
		boolean resultado = false;
		
		if(imagen != null)
		{
			cleanMemory();
		}
		
		if(selectedImage == null)
		{
			return resultado;
		}
		
		try
		{
			InputStream is = cr.openInputStream(selectedImage);
			BufferedInputStream bis = new BufferedInputStream(is);
			imagen = BitmapFactory.decodeStream(bis);
			resultado = true;
		}catch(FileNotFoundException e)
		{
			Traza.e(e);
			resultado = false;
		}
		
		Traza.d(Metodo.SALIDA);
		return resultado;
	}
	
	/**
	 * Libera la memoria ocupara por el bitmap para cargar uno nuevo.
	 */
	public void cleanMemory()
	{
		imagen.recycle();
		imagen = null;
		System.gc();
		Traza.i("Se ha liberado memoria del bitmap");
	}
	
	public Bitmap getImagen()
	{
		return imagen;
	}
	
	public Uri getLastUri()
	{
		return lastUri;
	}
	
	/**
	 * Crea el archivo donde se guardaea la imagen
	 * 
	 * @param type
	 * @return
	 */
	@SuppressLint("SimpleDateFormat")
	private File getOutputMediaFile(int type)
	{
		File mediaStorageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
		
		// Creamos el directorio si no existe
		if(!mediaStorageDir.exists())
		{
			if(!mediaStorageDir.mkdirs())
			{
				Traza.w("failed to create directory");
				return null;
			}
		}
		
		// Create a media file name
		String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
		File mediaFile;
		if(type == MEDIA_TYPE_IMAGE)
		{
			mediaFile = new File(mediaStorageDir.getPath() + File.separator + "IMG_" + timeStamp + ".jpg");
		}else
		{
			return null;
		}
		
		return mediaFile;
	}
	
	/**
	 * devuelve la Uri de la imagen creada
	 * 
	 * @param type
	 * @return
	 */
	public Uri getOutputMediaFileUri(int type)
	{
		File file = getOutputMediaFile(type);
		
		if(file == null)
		{
			/*
			 * Si no hay archivo se devuelbe null
			 */
			return null;
		}
		
		lastUri = Uri.fromFile(file);
		return lastUri;
	}
	
	/**
	 * Redimensiona la imagen proporcionalmente
	 * 
	 * @param width
	 * @param height
	 */
	public void redimensionar(int width)
	{
		Traza.d(Metodo.ENTRADA);
		if(imagen == null)
		{
			return;
		}
		
		Traza.i("Ancho solicitado: " + width);
		
		if(width > imagen.getWidth())
		{
			float ratio = imagen.getHeight() / imagen.getWidth();
			Traza.i("[ANTES]" + imagen.getHeight() + " x " + imagen.getWidth());
			
			int height = (int)(width * ratio);
			
			imagen = Bitmap.createScaledBitmap(imagen, width, height, false);
			Traza.i("[DESPUES]" + imagen.getHeight() + " x " + imagen.getWidth());
		}
		Traza.d(Metodo.SALIDA);
	}
	
	public void setImagenPorDefecto(int resId)
	{
		imagenPorDefecto = resId;
	}
}
